package com.zx.idc.backend.gui.api.management.infosecurity.violationwebsite.management.service.impl;

import com.alibaba.fastjson.JSON;
import com.zx.idc.backend.gui.api.commom.entity.CommandModel;
import com.zx.idc.backend.gui.api.commom.entity.factory.CommandAckFactory;
import com.zx.idc.backend.gui.api.commom.template.IdcCommandTransferTemplate;
import com.zx.idc.backend.gui.api.commom.utils.ExternalHelper;
import com.zx.idc.backend.gui.api.management.infosecurity.violationwebsite.management.service.NoFilterService;
import com.zx.idc.common.attributes.SchemaFileNameEnum;
import com.zx.idc.common.attributes.SystemAttributes;
import com.zx.idc.common.exception.EncryptException;
import com.zx.idc.ds.base.house.entity.BaseHouseInfo;
import com.zx.idc.ds.base.house.service.IBaseHouseInfoService;
import com.zx.idc.ds.common.constant.ReportStatusConstant;
import com.zx.idc.ds.ins.entity.InsAdminControl;
import com.zx.idc.ds.ins.service.IInsAdminControlService;
import com.zx.idc.ds.sys.entity.SysBlackWhiteList;
import com.zx.idc.ds.sys.service.ISysBlackWhiteListService;
import com.zx.idc.internal.exception.SendMessageException;
import com.zx.idc.internal.service.WhiteListInstructionService;
import com.zx.idc.xml.entity.NoFilter;
import com.zx.idc.xml.entity.idccommandack.IdcCommandAck;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

import static com.zx.idc.common.constants.IdcCommandAckTypeConstants.NOT_FILTER_WEBSITE_LIST_INSTRUCTION;

/**
 * Created by hasee on 2019/2/18.
 * 免过滤网站指令内容下发
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class NoFilterServiceImpl implements NoFilterService {
    protected final Logger LOG = LoggerFactory.getLogger(getClass());

    @Autowired
    private IInsAdminControlService iInsAdminControlService;

    @Autowired
    private ISysBlackWhiteListService iSysBlackWhiteListService;

    @Autowired
    private WhiteListInstructionService whiteListInstructionService;

    @Autowired
    private IBaseHouseInfoService iBaseHouseInfoService;

    @Autowired
    private IdcCommandTransferTemplate idcCommandTransferTemplate;

    @Override
    public void noFilter(NoFilter noFilter, CommandModel commandModel) {
        try {
            //1.添加到监管指令记录
            InsAdminControl insAdminControl = new InsAdminControl()
                .setIdcId(noFilter.getIdcId())
                .setInsContents(JSON.toJSONString(noFilter))
                .setReportStatus(ReportStatusConstant.NOT_REPORTED)
                .setCommandId(String.valueOf(noFilter.getCommandId()))
                .setCreateTime(LocalDateTime.now())
                .setInsType(SystemAttributes.INS_TYPE_NOFILTER);
            iInsAdminControlService.insert(insAdminControl);
            final int category = Objects.equals(noFilter.getType(), 1) ? 4 : 3;
            List<BaseHouseInfo> baseHouseInfos = iBaseHouseInfoService.selectList(new BaseHouseInfo().setIdcId(noFilter.getIdcId()));

            //2.添加/删除到黑白名单
            if (noFilter.getOperationType().equals(0)) {
                iSysBlackWhiteListService.insert(
                    new SysBlackWhiteList()
                        //活跃
                        .setStatus(1)
                        .setContent(noFilter.getContents())
                        .setPriority(noFilter.getLevel())
                        .setCategory(category)
                        .setCreateTime(LocalDateTime.now())
                        .setCommandId(noFilter.getCommandId())
                        .setSource(SysBlackWhiteList.SOURCE_WHITE_LIST)
                        .setEditable(SysBlackWhiteList.ONLY_READ)
                        .setComments("SMMS下发免过滤指令")
                );
                //优先级2进制转10进制
                noFilter.setLevel(String.valueOf(Integer.parseInt(noFilter.getLevel(), 2)));
                //调用内部接口
                try {
                    if (baseHouseInfos != null && !baseHouseInfos.isEmpty()) {
                        for (BaseHouseInfo baseHouseInfo : baseHouseInfos) {
                            whiteListInstructionService.addWhiteList(noFilter, String.valueOf(baseHouseInfo.getId()));
                        }
                    }
                } catch (EncryptException e) {
                    LOG.error("免过滤指令内容下发 添加白名单失败", e);
                    throw e;
                } catch (SendMessageException e) {
                    LOG.error("免过滤指令内容下发 添加白名单加密失败", e);
                    throw e;
                }
            } else if (noFilter.getOperationType().equals(1)) {
                iSysBlackWhiteListService.delete(
                    new SysBlackWhiteList()
                        .setCommandId(noFilter.getCommandId())
                );
                //优先级2进制转10进制
                noFilter.setLevel(String.valueOf(Integer.parseInt(noFilter.getLevel(), 2)));
                //调用内部接口
                try {
                    if (baseHouseInfos != null && !baseHouseInfos.isEmpty()) {
                        for (BaseHouseInfo baseHouseInfo : baseHouseInfos) {
                            whiteListInstructionService.delWhiteList(noFilter, String.valueOf(baseHouseInfo.getId()));
                        }
                    }
                } catch (EncryptException e) {
                    LOG.error("免过滤网站指令内容下发 删除白名单加密失败", e);
                    throw e;
                } catch (SendMessageException e) {
                    LOG.error("免过滤网站指令内容下发 删除白名单失败", e);
                    throw e;
                }
            }
            ExternalHelper.getExternalWebServiceEnable(() -> ackSuccess(noFilter, commandModel));

        } catch (Exception e) {
            LOG.error("免过滤网站列表指令出错 指令ID为:" + noFilter.getCommandId(), e);
            ExternalHelper.getExternalWebServiceEnable(() -> ackFailed(noFilter, commandModel));
            throw new RuntimeException("免过滤网站列表指令出错 指令ID为:" + noFilter.getCommandId(), e);
        }
    }

    private void ackSuccess(NoFilter noFilter, CommandModel commandModel) {
        //指令数据实体
        IdcCommandAck idcCommandAck = CommandAckFactory.ackSuccess(
            NOT_FILTER_WEBSITE_LIST_INSTRUCTION,
            commandModel,
            commandAck ->
                commandAck.setCommandId(noFilter.getCommandId())
        );
        //调用回调接口
        LOG.debug("调用管局回调接口...");
        idcCommandTransferTemplate.transferTemplate(commandModel, idcCommandAck, SchemaFileNameEnum.INFO_SECURITY_MANAGEMENT);
    }

    private void ackFailed(NoFilter noFilter, CommandModel commandModel) {
        //指令数据实体
        IdcCommandAck idcCommandAck = CommandAckFactory.ackFail(
            NOT_FILTER_WEBSITE_LIST_INSTRUCTION,
            commandModel,
            "网络错误，请销后重试!",
            commandAck ->
                commandAck.setCommandId(noFilter.getCommandId())
        );
        //调用回调接口
        LOG.debug("调用管局回调接口...");
        idcCommandTransferTemplate.transferTemplate(commandModel, idcCommandAck, SchemaFileNameEnum.INFO_SECURITY_MANAGEMENT);
    }
}
